package AS_source
{
	import Components.*;
	
	import com.adobe.utils.XMLUtil;
	import com.adobe.xml.syndication.rss.Item20;
	import com.adobe.xml.syndication.rss.RSS20;
	
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	
	import mx.containers.Accordion;
	import mx.containers.ApplicationControlBar;
	import mx.containers.TabNavigator;
	import mx.containers.VBox;
	import mx.controls.Alert;
	import mx.controls.ComboBox;
	import mx.controls.Text;
	import mx.rpc.events.FaultEvent;
	
	public class RankSearch
	{
		var tabNavi:TabNavigator;
		var searchNavi:Accordion;
		var searchTabOutput:VBox;
		var specHelper:XML;
		var concenXML:XML;
		private var loader:URLLoader;

//url of rss 2.0 feed
		private static const RSS_URL1:String="http://pipes.yahoo.com/pipes/pipe.run?_id=0235615a1953b1385cda27b88ee3491c&_render=rss";
		private var specialties:String;
		private var schoolXML:XML;
		private var specVal:Boolean = false; 

		public var genFieldListing:Array=[{label: "Best Business Schools", data: "business"}, 
			{label: "Best Law Schools", data: "law"}, 
			{label: "Best Engineering Schools", data: "engineering"}, 
			{label: "Best Education Schools", data: "education"},
			{label: "Best Public Affairs Schools", data: "public-affairs"}, 
			{label: "Best Fine Arts Schools", data: "fine-arts"}, 
			{label: "Best Biology Schools", data: "biology"}, 
			{label: "Best Chemistry Schools", data: "chemistry"}, 
			{label: "Best Political Science Schools", data: "political-science"}, 
			{label: "Best Economics Schools", data: "economics"}, 
			{label: "Best Computer Science Schools", data: "computer-science"}, 
			{label: "Best Psychology Schools", data: "psychology"}, 
			{label: "Best Computer Science Schools", data: "computer-science"}, 
			{label: "Best Sociology Schools", data: "sociology"}
			];

		public function RankSearch(tabControl:TabNavigator, searchControl:Accordion)
		{
			tabNavi=tabControl;
			searchNavi=searchControl;
			this.getConcentrations();
		}

		public function getDataProvider():Array
		{

			return genFieldListing;
		}

		function genURLListing(field:String):String
		{
			return "http://grad-schools.usnews.rankingsandreviews.com/best-graduate-schools/top-" + field + "-schools/rankings";
		}

		//use true if you want to get a listing of the spec fields false otherwise

		function obtainHTML(url:String, spec:Boolean):void
		{
			var assetLoader:URLLoader=new URLLoader();
			var request:URLRequest=new URLRequest(url);
			assetLoader.load(request);
			if (spec)
			{
				assetLoader.addEventListener(Event.COMPLETE, loadSpecComplete);
			}
			else
			{
				assetLoader.addEventListener(Event.COMPLETE, loadPageComplete);
			}
			assetLoader.addEventListener(FaultEvent.FAULT, failureHandler);
		}

		public function getfieldListing():Array
		{
			return this.genFieldListing;
		}

		function loadPageComplete(e:Event):void
		{	
			var pageText:String=String(e.currentTarget.data);
			var oppattern:RegExp=/<tbody>/gx;
			var clpattern:RegExp=/<\/tbody>/gx;
			var closedTag:String=String(clpattern);
			var openIndex:int=pageText.search(oppattern);
			var closeIndex:int=pageText.search(clpattern);
			var tableText:String=pageText.substring(openIndex, closeIndex + closedTag.length);
			// Get html <table> into xml format
			var htmlXML:XML=XML(tableText);
			// Get schools into xml format by creating a "well formated" subXML structure
			if(getSpec()){//specialized w/i the general
				var schoolStr:String="<schoolList>  \n" + htmlXML.children().toString() + " \n </schoolList>";				
			}else{//just plain general
				var schoolStr:String="<schoolList>  \n" + htmlXML.tr.(attribute("class") == "school-title") + " \n </schoolList>";	
			}
			

			var schoolXML:XML=new XML(schoolStr);
			var tester:VBox=VBox(searchNavi.getChildByName("rankSearch"));
			var txtBox:Text=Text(tester.getChildByName("textBox"));
			var rank:int=0;
			this.clearOutput();
			//Alert.show("Here is schoolXML " + schoolXML);
			for each (var gradSchool:XML in schoolXML.tr)
			{
				rank=rank + 1;
				var schoolName:String=gradSchool.td.(attribute("class") == "school").a.(attribute("href"));
				var address:String=gradSchool.td.(attribute("class") == "school").address;
				var schoolInfo:SchoolPanel= new SchoolPanel();
				//ADD CUSTOM COMPONENT BEFORE YOU MODIFY
				searchTabOutput.addChild(schoolInfo);
				schoolInfo.title = schoolName;
				schoolInfo.locationLabel.text = address;
				schoolInfo.rankLabel.text = String(rank);
			}
		}

		function loadSpecComplete(e:Event):void
		{
			var pageText:String=String(e.currentTarget.data);
			var oppattern:RegExp=/<table>/gx;
			var clpattern:RegExp=/<\/table>/gx;
			var closedTag:String=String(clpattern);
			var openIndex:int=pageText.search(oppattern);
			var closeIndex:int=pageText.search(clpattern);
			var tableText:String=pageText.substring(openIndex, closeIndex + closedTag.length);
			// Get html <table> into xml format
			var htmlXML:XML=XML(tableText);
			// Get schools into xml format by creating a "well formated" subXML structure
			//NOTE THAT THIS CHANGES DEPENDING IF WE ARE DEALING WITH GENERAL PROGRAM OR SPEC'S 
			var schoolStr:String="<schoolList>  \n" + htmlXML.children().toString() + " \n </schoolList>";
			var schoolXML:XML=new XML(schoolStr);
			var rank:int=0;
			var prevRank:int=0;
			clearOutput();
			for each (var gradSchool:XML in schoolXML.tr)
			{
				//used for the case that they use 0 to mean duplicates.
				rank=Number(gradSchool.td.(attribute("class") == "rank"));
				var schoolName:String=gradSchool.td.(attribute("class") == "school").a.(attribute("href"));
				var address:String=gradSchool.td.(attribute("class") == "school").address;
				var schoolInfo:SchoolPanel = new SchoolPanel();
				searchTabOutput.addChild(schoolInfo);
				if (rank == 0)
				{ //we have duplicate ranking so use the old one
				//ADD CUSTOM COMPONENT BEFORE YOU MODIFY
				schoolInfo.title = schoolName;
				schoolInfo.locationLabel.text = address;
				schoolInfo.rankLabel.text = prevRank.toString();
				}
				else
				{
				schoolInfo.title = schoolName;
				schoolInfo.locationLabel.text = address;
				schoolInfo.rankLabel.text = rank.toString();
				prevRank=rank;	
				}
				
			}
		}

		function failureHandler(e:Event):void
		{
			Alert.show("HTML Load Failure");
		}

		public function searchButtonEvt(e:Event):void
		{

			var rankSearch:Rank_Search_VBox=Rank_Search_VBox(searchNavi.getChildByName("rankSearch"));
			var controlBar:ApplicationControlBar=ApplicationControlBar(rankSearch.getChildByName("genControlBar"))
			var genBox:VBox=VBox(controlBar.getChildByName("genVBox"));
			var selectionString:String=ComboBox(genBox.getChildByName("genComboBox")).selectedItem.label;
			var selectionInt:int=ComboBox(genBox.getChildByName("genComboBox")).selectedItem.selectedIndex;
			var selectionData:String=ComboBox(genBox.getChildByName("genComboBox")).selectedItem.data;
			///Check the concentration value and ensure that it is nonempty
			var rankSearch:Rank_Search_VBox=Rank_Search_VBox(searchNavi.getChildByName("rankSearch"));
			var controlBar:ApplicationControlBar=ApplicationControlBar(rankSearch.getChildByName("specControlBar"))
			var specBox:VBox=VBox(controlBar.getChildByName("specVBox"));
			var specSelectedIndex:int=ComboBox(specBox.getChildByName("specComboBox")).selectedIndex;
			this.setupWriter(); // writes to output
			//if selection is a concentration
			if (specSelectedIndex != -1)
			{
				this.setSpec(true);
				this.obtainHTML(getSpecialtyLink(getGenField(selectionData), specSelectedIndex), true);
			}//If we choose one of the spec's that are in the general combobox
			else if((selectionData == "biology") ||(selectionData == "chemistry") ||
			(selectionData == "political-science") || (selectionData == "economics") ||
			(selectionData == "computer-science") || (selectionData == "psychology") ||
			(selectionData == "sociology")){
				this.setSpec(true);
				this.obtainHTML(genURLListing(selectionData), false);
				
			}
			else
			{
				//if selection is a generality
				this.setSpec(false);
				this.obtainHTML(genURLListing(selectionData), false);
			}
			//set the focus of the tab to be the current one
			tabNavi.selectedIndex = tabNavi.getChildIndex(tabNavi.getChildByName("searchContents"));
		}
		private function setSpec(isSpec:Boolean):void{
			specVal = isSpec;
		}
		private function getSpec():Boolean{
			return specVal;
		}
		public function comboChangeEvt(e:Event):void
		{
			var rankSearch:Rank_Search_VBox=Rank_Search_VBox(searchNavi.getChildByName("rankSearch"));
			var controlBar:ApplicationControlBar=ApplicationControlBar(rankSearch.getChildByName("genControlBar"))
			var genBox:VBox=VBox(controlBar.getChildByName("genVBox"));
			var selectionString:String=ComboBox(genBox.getChildByName("genComboBox")).selectedItem.label;
			//Update the specific concentrations
			var rankSearch:Rank_Search_VBox=Rank_Search_VBox(searchNavi.getChildByName("rankSearch"));
			var controlBar:ApplicationControlBar=ApplicationControlBar(rankSearch.getChildByName("specControlBar"))
			var specBox:VBox=VBox(controlBar.getChildByName("specVBox"));
			var listing:XMLList=getSpecialtyProgs(ComboBox(genBox.getChildByName("genComboBox")).selectedItem.data);
			if(listing==null){
				ComboBox(specBox.getChildByName("specComboBox")).enabled=false;
			}else{
				ComboBox(specBox.getChildByName("specComboBox")).enabled=true;
				
			}
			ComboBox(specBox.getChildByName("specComboBox")).dataProvider=listing;
			
		}

		/*Used to get the field from general combobox */
		private function getGenField(genField:String):String
		{
			/* parse out unnecessary stuff and format string */
			genField=genField.replace("Best ", "");
			genField=genField.replace(" Schools", "");
			genField=genField.replace(" ", "-");
			genField=genField.toLowerCase();
			return genField;
		}

		/*
		 *	Clear the output of the display
		 */
		private function clearOutput():void
		{
			searchTabOutput.removeAllChildren();
		}

		private function getSpecialtyProgs(area:String):XMLList
		{
			area=area.concat("-links");
			var results:XMLList;
			for each (var program:XML in getSchoolXML().children())
			{
				var specialtyXML:XML=new XML(program);

				if (program.attribute("class") == area)
				{
					results=specialtyXML.li.a.children();
				}
			}
			return results;
		}

		private function getSpecialtyLink(area:String, position:int):String
		{
			area=area.concat("-links");
			var results:String;
			for each (var program:XML in getSchoolXML().children())
			{
				
				var specialtyStr:String=program;
				var specialtyXML:XML=new XML(program);
				if (program.attribute("class") == area)
				{
					
					results=specialtyXML.li.a.attribute("href")[position].toString();
				}
			}
			
			return results;
		}

		/*
		   Used to setup output to the tab
		 */
		private function setupWriter()
		{
			var tester:VBox=VBox(tabNavi.getChildByName("searchContents"));
			var outBox:VBox=VBox(tester.getChildByName("insertBox"));
			searchTabOutput=outBox;
		}

		public function getConcentrations():void
		{
			loadRSSToXML(RSS_URL1); //LEAVE ALONE
		}

		private function loadRSSToXML(URL:String)
		{
			loader=new URLLoader();
			//request pointing to feed
			var request:URLRequest=new URLRequest(URL);
			request.method=URLRequestMethod.GET;
			//listen for when the data loads
			loader.addEventListener(Event.COMPLETE, onDataLoad);
			//listen for error events
			loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
			//load the feed data
			loader.load(request);

		}

//called once the data has loaded from the feed
		private function onDataLoad(e:Event):void
		{
			//get the raw string data from the feed
			var rawRSS:String=URLLoader(e.target).data;
			//parse it as RSS
			parseRSS(rawRSS);

		}

//parses RSS 2.0 feed and prints out the feed titles into
//the text area
		private function parseRSS(data:String):void
		{
			//XMLSyndicationLibrary does not validate that the data contains valid
			//XML, so you need to validate that the data is valid XML.
			//We use the XMLUtil.isValidXML API from the corelib library.
			var schoolPrograms:String="";
			if (!XMLUtil.isValidXML(data))
			{
				Alert.show("Feed does not contain valid XML.");
				return;
			}
			//create RSS20 instance
			var rss:RSS20=new RSS20();

			//parse the raw rss data
			rss.parse(data);

			//get all of the items within the feed
			var items:Array=rss.items;

			//loop through each item in the feed
			for each (var item:Item20 in items)
			{
				schoolPrograms+=item.title
			}
			var schoolStr:String="<programList>  \n" + schoolPrograms + " \n </programList>";
			setSchoolXML(new XML(schoolStr));
		}

		public function getSchoolXML():XML
		{
			return schoolXML;
		}

		private function setSchoolXML(data:XML)
		{
			schoolXML=data;
		}

		private function onIOError(e:IOErrorEvent):void
		{
			Alert.show("IOError : " + e.text);
		}

		private function onSecurityError(e:SecurityErrorEvent):void
		{
			Alert.show("SecurityError : " + e.text);
		}

	}
}